package com.learn.step03_functions

import java.time.LocalDate

/**
 *
 *
 * @author: hbliy
 * @date: 2025/7/9 15:23
 */

fun main(args: Array<String>) {
    println({
        val currentYear = LocalDate.now().year
        "Welcome to SimVillage, Mayor! (copyright $currentYear)"
    }())

    println(greetingFunction())

    println(sum2(4, 5))
    println(test(4, 5, sum2))
    println(test(4, 5, { a, b -> a * b }))

    println(greetingFunction2("zhansan"))
    println(greetingFunction3("lisi"))

    val currentYear = LocalDate.now().year
    println(greetingFunction4("wangwu", currentYear))

    val greetingFunction6 = { playerName: String, year: Int ->
        "Welcome to SimVillage, $playerName! (copyright $year)"
    }

    runSimulation("zhangsan", greetingFunction6)
    runSimulation("zhangsanfeng", { playerName: String, year: Int ->
        "Welcome to SimVillage, $playerName! (copyright $year)"
    })

    println("Mississippi".count({ it == 's' }))
//    如果一个函数的lambda参数排在最后，或者是唯一的参数，那么括住lambda值参的一对圆括号就可以省略。
    println("Mississippi".count { it == 's' })


    // 函数引用
    runSimulation2("张三", ::printConstructionCost, { playerName, numBuildings ->
        val currentYear = LocalDate.now().year
        println("Adding $numBuildings houses")
        "Welcome to SimVillage, $playerName! (copyright $currentYear)"
    })

    // 尾随 lambda 写法（更简洁）
    runSimulation2("张三", ::printConstructionCost) { playerName, numBuildings ->
        val currentYear = LocalDate.now().year
        println("Adding $numBuildings houses")
        "Welcome to SimVillage, $playerName! (copyright $currentYear)"
    }

    // 函数类型作为返回类型
    runSimulation3();
}


/**
 * 匿名函数
 */
val greetingFunction: () -> String = {
    val currentYear = LocalDate.now().year
    "Welcome to SimVillage, Mayor! (copyright $currentYear)"
}

/**
 * 函数参数
 */
val greetingFunction2: (String) -> String = { playerName ->
    val currentYear = LocalDate.now().year
    "Welcome to SimVillage, $playerName! (copyright $currentYear)"
}

/**
 * it 关键字
 */
val greetingFunction3: (String) -> String = {
    val currentYear = LocalDate.now().year
    "Welcome to SimVillage, $it! (copyright $currentYear)"
}

/**
 * 多个参数
 */
val greetingFunction4: (String, Int) -> String = { playerName, year ->
    "Welcome to SimVillage, $playerName! (copyright $year)"
}

/**
 * 类型推断
 */
val greetingFunction5 = { playerName: String, year: Int ->
    "Welcome to SimVillage, $playerName! (copyright $year)"
}

var sum2: (a: Int, b: Int) -> Int = { a, b ->
    a + b
}

var sum22: (Int, Int) -> Int = { a, b ->
    a + b
}

// sum2 的简写方式
val sum3 = { a: Int, b: Int -> a + b }

fun test(a: Int, b: Int, sum: (a: Int, b: Int) -> Int): Int {
    return sum(a, b)
}

// 表达式函数，test 的简写方式，省略返回类型、大括号和 return
fun test2(a: Int, b: Int, sum: (a: Int, b: Int) -> Int) = sum(a, b)


/**
 * 定义参数是函数的函数
 */
inline fun runSimulation(playerName: String, greetingFunction: (String, Int) -> String) {
    // Randomly selects 1, 2, or 3
    val numBuildings = (1..3).shuffled().last()

    println(greetingFunction(playerName, numBuildings))
}

inline fun runSimulation2(
    playerName: String,
    costPrinter: (Int) -> Unit,
    greetingFunction: (String, Int) -> String
) {
    // Randomly selects 1, 2, or 3
    val numBuildings = (1..3).shuffled().last()
    costPrinter(numBuildings)
    println(greetingFunction(playerName, numBuildings))
}

/**
 * 函数引用
 *
 */
inline fun printConstructionCost(numBuildings: Int) {
    val cost = 400
    println("construction cost: ${cost * numBuildings}")
}

/**
 * 函数类型作为返回类型
 */
fun configureGreetingFunction():(String) -> String {
    val structureType = "hospitals"
    var numBuildings = 5
    return { playerName: String ->
        val currentYear = LocalDate.now().year
        numBuildings += 1
        println("Adding $numBuildings $structureType")
        "Welcome to SimVillage, $playerName! (copyright $currentYear)"
    }
}

fun runSimulation3 () {
    val greetingFunction = configureGreetingFunction()
    println(greetingFunction("zhangsan"))
    println(greetingFunction("zhangsan"))

    println(configureGreetingFunction()("lisi"))
}